///////////////////////////////////////////////////////////////////////////////
//
// lighthouse3D - 3D Software Library
//
// File: C3DSFileHandler.h
//
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2003-2013 Marcus Reinhardt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
///////////////////////////////////////////////////////////////////////////////
//
// You can find a copy of the GNU General Public License (gpl.txt) in the
// directory of the library.
//
///////////////////////////////////////////////////////////////////////////////

#ifndef _C3DSFileHandler_H_
#define _C3DSFileHandler_H_

#include <iostream>

#include "CBasicClasses.h"
#include "CMeshStorage.h"

///////////////////////////////////////////////////////////////////////////////
// class C3DSFileHandler : A class to load 3DS Files
///////////////////////////////////////////////////////////////////////////////
//
// This class implements a 3DS loader! Parts of this class contain code I found
// in the internet.
//
// Following kinds of data chunks are considered
// * Triangular mesh objects (Vertexes, Faces, Parts of the Material and TexUV)
// * Material (Name, Texturefilename)
// Other datas (lights, cameras, etc...) are simply ignored!
//
///////////////////////////////////////////////////////////////////////////////

#define CHUNK_MAIN                         0x4d4d

#define CHUNK_EDIT                         0x3d3d
#define CHUNK_EDIT_OBJECT                  0x4000
#define CHUNK_EDIT_OBJECT_TRIMESH          0x4100
#define CHUNK_EDIT_OBJECT_TRIMESH_VERTS    0x4110
#define CHUNK_EDIT_OBJECT_TRIMESH_FACES    0x4120
#define CHUNK_EDIT_OBJECT_TRIMESH_MATERIAL 0x4130
#define CHUNK_EDIT_OBJECT_TRIMESH_TEXUV    0x4140
#define CHUNK_EDIT_OBJECT_TRIMESH_SMOOTH   0x4150

#define CHUNK_EDIT_MATERIAL                0xAFFF
#define CHUNK_EDIT_MATERIAL_MATNAME        0xA000
#define CHUNK_EDIT_MATERIAL_AMBIENT        0xA010
#define CHUNK_EDIT_MATERIAL_DIFFUSE        0xA020
#define CHUNK_EDIT_MATERIAL_SPECULAR       0xA030
#define CHUNK_EDIT_MATERIAL_TEXTURE        0xA200
#define CHUNK_EDIT_MATERIAL_BUMPMAP        0xA230
#define CHUNK_EDIT_MATERIAL_TEXFILENAME    0xA300

#define CHUNK_HEADER_SIZE                  6

#define maxTextures                        1024

#define disableDebug                       true

//! Contains one texture description and filename

struct TTexDescription
{
  char fileName[256];
  
  char description[512];
};

//! Contains every texture description and filename after importing a 3DS-file

struct TTextureList
{
  int n;
  
  TTexDescription textures[maxTextures];
};

//! A class to import 3D-Studio files (*.3ds)

class C3DSFileHandler
{

public:

    C3DSFileHandler();
    ~C3DSFileHandler();
    
    bool load3DSFile(const char *fname, CMeshStorage *storageHandler);
    bool loadChunkHeader(FILE *f, int &chunkID, int &chunkLength);
    void skipChunk(FILE *f, int chunkLength);
    
    bool loadMainChunk(FILE*, int length);
    bool loadEditorChunk(FILE*, int length);
    bool loadMaterialChunk(FILE *f, int length);
    bool loadObjectChunk(FILE*, int length, const char*);
    bool loadTriMeshChunk(FILE*, int length);
    
    int addTexture(char *matName);
    int getTextureNr(char *matName);
    
    ////////////////////////////////////////////////////////////////////////////
    // The following routines are for debugging! They are disabled for the
    // moment. If you enable them you will get a lots of information about the
    // 3DS file.
    ////////////////////////////////////////////////////////////////////////////
    void writeDebugText(char *text) { if (!disableDebug) fprintf(logFile, text); }
    void writeDebugInt(int i) { if (!disableDebug) fprintf(logFile, "%i", i); }
    void writeDebugFloat(float f) { if (!disableDebug) fprintf(logFile, "%f", f); }
    
    TTextureList *getTexListHandle() { return &texList; }
    
private:

    FILE *logFile;
    
    int latestAddedTex;
    int statsMeshCount;
    int statsTotalVerts;
    int statsTotalFaces;

    CMeshStorage *pMeshStorage;
    
    TTextureList texList;

};

#endif
